import type { Page } from '@/models';
import { Result } from '@/utils/request/type';
import type { TableProps } from 'antd';
import { Table } from 'antd';
import type { ColumnsType, TableRowSelection } from 'antd/lib/table/interface';
import type { TransferItem } from 'antd/lib/transfer';
import { difference } from 'lodash-es';
import type { FC } from 'react';
import { memo } from 'react';
import styled from 'styled-components';
import type { BaseTransferProps } from '.';
import Transfer from '.';

export type TableTransferRequest<T extends Record<string, unknown>> = (
  params: T & {
    pageSize?: number | undefined;
    pageNum?: number | undefined;
  }
) => Result<Page<T>>;

type RecordType = TransferItem;
/**
 * tableTransferProps,拓展了leftColumns、rightColumns、leftProps、rightProps
 */
export interface TableTransferProps<T extends Record<string, unknown>>
  extends BaseTransferProps<RecordType> {
  leftColumns?: ColumnsType<T>;
  rightColumns?: ColumnsType<T>;
  leftProps?: TableProps<T>;
  rightProps?: TableProps<T>;
  bodyHeight?: string | number;
}
// 封装样式
export const TableTransferWrap = styled(Transfer)<{ bodyHeight: string | number }>`
  .ant-table-container > .ant-table-body {
    height: ${({ bodyHeight }) =>
      typeof bodyHeight === 'number' ? `${bodyHeight}px` : bodyHeight};
    tr.ant-table-placeholder {
      td {
        border: none;
      }
    }
  }
`;
/**
 * 封装table和transfer组件，实现表格形式的穿梭框组件，props基于TransferProps，拓展了leftColumns、rightColumns、leftProps、rightProps属性，用于传入表格数据
 * leftProps、rightProps基于ant table
 */
const BaseTableTransfer: FC<TableTransferProps<any>> = memo(
  ({
    leftColumns,
    rightColumns,
    leftProps,
    rightProps,
    bodyHeight = 'auto',
    targetKeys,
    ...restProps
  }) => {
    return (
      <TableTransferWrap
        bodyHeight={bodyHeight}
        targetKeys={targetKeys}
        {...restProps}
        showSelectAll={false}
      >
        {/* 自定义transfer渲染 */}
        {({
          direction,
          filteredItems,
          onItemSelectAll,
          onItemSelect,
          selectedKeys: listSelectedKeys,
          disabled: listdisabled
        }) => {
          // 判断渲染列
          const columns = direction === 'left' ? leftColumns : rightColumns;
          const tableProps = direction === 'left' ? leftProps : rightProps;
          // 设置表格多行选择功能
          const rowSelection: TableRowSelection<any> = {
            getCheckboxProps: (item) => ({ disabled: listdisabled || item.disabled }),
            onSelectAll(selected, selectedRows) {
              // 获取选中key
              const treeSelectedKeys = selectedRows
                .filter((item) => !item.disabled)
                .map(({ key }) => key);
              // 根据是否选中将当前页的key进行删除或增加
              const diffKeys = selected
                ? difference(treeSelectedKeys, listSelectedKeys)
                : difference(listSelectedKeys, treeSelectedKeys);
              onItemSelectAll(diffKeys, selected);
            },
            onSelect({ key }, selected) {
              onItemSelect(key, selected);
            },
            selectedRowKeys: listSelectedKeys
          };
          return (
            <Table
              bordered
              rowClassName={(record: any, index: number, indent: any) => {
                const classnames = [index % 2 === 0 ? 'even' : 'odd'];
                if (tableProps && tableProps.rowClassName) {
                  const { rowClassName } = tableProps;
                  if (typeof rowClassName === 'string') {
                    classnames.push(rowClassName);
                  } else {
                    classnames.push(rowClassName(record, index, indent));
                  }
                }

                return classnames.join(' ');
              }}
              {...tableProps}
              style={
                {
                  pointerEvents: listdisabled ? 'none' : undefined
                } as any
              }
              rowSelection={rowSelection}
              columns={columns}
              dataSource={filteredItems as any}
              scroll={{ y: bodyHeight }}
              pagination={{ simple: true }}
              onRow={({ key, disabled: itemDisabled }) => ({
                onClick: () => {
                  if (itemDisabled || listdisabled) return;
                  onItemSelect(key, !listSelectedKeys.includes(key));
                }
              })}
            />
          );
        }}
      </TableTransferWrap>
    );
  }
);
export default BaseTableTransfer;
